home *** CD-ROM | disk | FTP | other *** search
/ Aminet 32 / Aminet 32 (1999)(Schatztruhe)[!][Aug 1999].iso / Aminet / util / libs / graphics3d.lha / src / library / graphics3d2d_o.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-02-16  |  25.7 KB  |  1,252 lines

  1. /*
  2. **      $VER: graphics3D2d_o.c 10.00 (06.05.98)
  3. **
  4. **      Internal functions for graphics3D.library
  5. **     Optimezed 2D functions
  6. **    
  7. **      (C) Copyright 98 Patrizio Biancalani
  8. **      All Rights Reserved.
  9. */
  10.  
  11. #include <exec/types.h>
  12. #include <exec/memory.h>
  13. #include <proto/exec.h>
  14. #include <proto/intuition.h>
  15. #include <intuition/intuition.h>
  16. #include <intuition/screens.h>
  17.  
  18. #include <graphics/rastport.h>
  19. #include <graphics/clip.h>
  20. #include <graphics/regions.h>
  21. #include <graphics/gfx.h>
  22. #include <graphics/gfxmacros.h>
  23. #include <graphics/layers.h>
  24.  
  25. #include "graphics3Dc.h"
  26. #include "graphics3D.h"
  27. #include "graphics3D2d_proto.h"
  28.  
  29.  /* Please note, that &Graphics3DBase always resides in register __a6 
  30.     as well, but if we don't need it, we need not reference it here.
  31.  
  32.     Also note, that registers a0, a1, d0, d1 always are scratch registers,
  33.     so you usually should only *pass* parameters there, but make a copy
  34.     directly after entering the function. To avoid problems of kind
  35.     "implementation defined behaviour", you should make a copy of A6 too,
  36.     when it is actually used.
  37.  
  38.     In this example case, scratch register saving would not have been 
  39.     necessary (since there are no other function calls inbetween), but we 
  40.     did it nevertheless.
  41.   */
  42.  
  43. /************ prototipi solo locali ******/
  44. struct RastPort *InitNBuff(struct grafica *graf);
  45. void line2(struct ambient3d *amb3d, long int x, long int y, long int z, long int x1,
  46.     long int y1, long int z1, long int col);
  47.  
  48. void FreeNBuff(struct grafica *graf);
  49.  
  50. /**********************************************************/
  51.  
  52. /************ macro solo locali ******/
  53. #define DIPIU 500 
  54. #define PREC 8
  55. #define DISP (6*FIXV)
  56. #define D_TMAP sizeof(Sbuftmap)*TTMAP+DIPIU
  57. /*************************************/
  58.  
  59. /****************************************************
  60.  ** Routin per la gestione della grafica, in stile **
  61.  ** 2.0 Ottimizzate                                ** 
  62.  ** (c) 1994 BIANCA HARD&SOFT Vers:1.00            **
  63.  ****************************************************/
  64.  
  65. /********* FUNZIONI DI INIZIALIZAZIONE PER IL 2D ********************************/
  66.  
  67. /***********************************
  68.  ** INIZIALIZZO STRUTTURE PER USO **
  69.  ** CON ROUTIN  OTTIMIZZATE.      **
  70.  ***********************************
  71.  **** INPUT :              **
  72.  ** win -> puntatore a finestra   **
  73.  **        su cui lavorare.       **
  74.  ** mxv -> n# massimo vertici da  **
  75.  **        usare.          **
  76.  ** dx -> larghezza box di visual.**
  77.  ** dy -> altezza box di visual.  **
  78.  **** OUTPUT :                    **
  79.  ** ris >0  - tutto ok.           **
  80.  ** ris =<0 - errore, ini.fallita.**
  81.  ***********************************/
  82. struct grafica *ini_g(struct Window *win,long int mxv,long int dx,long int dy)
  83. {
  84. struct grafica *ris;
  85. struct Screen *scr;
  86. struct RastPort *rw;
  87. struct RastPort *r;
  88. struct buftmap *btm;
  89. long int i,x,y;
  90.  
  91. ris=(struct grafica *)AllocMem(sizeof(Sgrafica),NULL);
  92. if (ris==NULL) return (0);
  93.  
  94. ris->vpor=0;
  95. ris->rast=0;
  96. ris->rast1=0;
  97. ris->rast2=0;
  98. ris->zbuf=0;
  99. ris->fdouble=1;
  100. ris->b_af=0;
  101. ris->pras=0;
  102. ris->t_color=0;
  103. ris->a_tmap=0;
  104.  
  105. x=dx;
  106. y=dy;
  107. if (x>MAXDX) x=MAXDX;
  108. if (y>MAXDY) y=MAXDY;
  109.  
  110. /** default si single buffer **/
  111. ris->clipx=0;
  112. ris->clipy=0;
  113. i=((x+15)/16)*16;
  114. ris->clipdx=i;
  115. ris->clipdy=y;
  116. ris->dbuf=0;
  117. ris->ldbuf=0;
  118. ris->tmp_rp.BitMap=0;
  119.  
  120. rw=win->RPort;
  121. scr=win->WScreen;
  122. ris->vpor=&(scr->ViewPort);
  123. ris->wind=win;
  124.  
  125. ris->depth=1<<(rw->BitMap->Depth);
  126. ris->r_color=4;                /* n# colori da non usare nella gen. palette */
  127. ris->n_level=ris->depth - ris->r_color;    /* n# livelli intensita' per ogni colore */
  128. ris->n_color=1;                /* n# colori base nella palette */
  129.  
  130. i=(long int)AllocMem(LEN_TABC,NULL);    /* alloco memoria per tabella colori base */
  131. if (i==NULL)
  132.     {
  133.     close_g(ris);
  134.     return(0);
  135.     }    
  136. ris->t_color=(long int *)i;
  137.  
  138. i=(long int)AllocMem(D_TMAP,NULL);    /* alloco memoria per tabella texture map */
  139. if (i==NULL)
  140.     {
  141.     close_g(ris);
  142.     return(0);
  143.     }
  144. ris->a_tmap=(struct buftmap *)i;
  145. btm=(struct buftmap *)i;
  146. /* setto tutti gli elementi come vuoti */
  147. for(i=0 ;i<TTMAP ;i++) btm[i].chunky=0;
  148.  
  149. r=InitNBuff(ris);
  150. if ((long int)r==NULL) {
  151.     close_g(ris);
  152.     return(0);
  153.     }
  154. ris->rast1=rw;
  155. ris->rast2=r;
  156. ris->rast=r;
  157.  
  158. return(ris);
  159. }
  160.  
  161. /***********************************
  162.  ** Apro un area per lo Z-buffer  **
  163.  ** se non gia' esistente.      **
  164.  ***********************************
  165.  *** INPUT :               *
  166.  * in -> valore >0 restituito da   *
  167.  *      display3d.                *
  168.  *** OUTPUT:                   *    
  169.  * 0 - operazione fallita.       *
  170.  * 1 - operazione riuscita.       * 
  171.  ***********************************/
  172. long int c_zbuf(struct ambient3d *in)
  173. {
  174. struct grafica *graf;
  175.  
  176. graf=in->graf;
  177.  
  178. if (graf->zbuf!=NULL) return(1);    /* area per zbuffering gia' esistente */
  179.  
  180. graf->lzbuf=in->maxx*in->maxy*(sizeof(long int))+DIPIU;
  181.  
  182. graf->zbuf=(long int *)AllocMem(graf->lzbuf,NULL);
  183. if (graf->zbuf==NULL) return(0);
  184.  
  185. return(1);
  186. }
  187.  
  188. /***********************************
  189.  ** CHIUDO TUTTE LE STRUTTURE     **
  190.  ** APERTE CON LA FUNZIONE PRECE- **
  191.  ** DENTE.                        **
  192.  ***********************************
  193.  **** INPUT :                     **
  194.  ** graf -> valore >0 ritornato   **
  195.  **         dalla funzione d'ini- **
  196.  **         zializzazione         **
  197.  ***********************************/
  198. void close_g(struct grafica *graf)
  199. {
  200. struct RastPort *r;
  201. struct Layer *la;
  202. struct buftmap *btm;
  203. long int i;
  204.  
  205. if ((long int)graf != NULL)
  206.     {
  207.     if (graf->t_color!=NULL) FreeMem(graf->t_color,LEN_TABC);
  208.     if (graf->a_tmap!=NULL) 
  209.         {
  210.         btm=graf->a_tmap;
  211.         for(i=0; i<TTMAP; i++)
  212.             {
  213.             if (btm[i].chunky!=NULL)
  214.                 {
  215.                 FreeMem(btm[i].chunky,btm[i].lung);
  216.                 btm[i].chunky=0;
  217.                 }    
  218.             }
  219.         FreeMem(graf->a_tmap,D_TMAP);
  220.         }
  221.     if (graf->zbuf!=NULL) FreeMem(graf->zbuf,graf->lzbuf);
  222.     if (graf->dbuf!=NULL) FreeNBuff(graf);
  223.     FreeMem(graf,sizeof(Sgrafica));
  224.     }
  225. }
  226.  
  227. /************************************
  228.  ** FUNZIONE PER VISUALIZZARE IL   **
  229.  ** DISPLAY BUFFER CHUNKY NELLA    **
  230.  ** FINESTRA.               **
  231.  ************************************
  232.  **** INPUT :               **
  233.  ** graf -> valore >0 ritornato    **
  234.  **         dalla funzione d'ini-  **
  235.  **         zializzazione.         **
  236.  **** OUTPUT:               **
  237.  ************************************/
  238. void switch_rp(graf)
  239. struct grafica *graf;
  240. {
  241. long int x,y;
  242.  
  243. x=graf->clipx;
  244. y=graf->clipy;
  245.  
  246. if (graf) WritePixelArray8(graf->rast,x,y,x+graf->clipdx-1,y+graf->clipdy-1,
  247.         graf->dbuf,&graf->tmp_rp);
  248.  
  249. }
  250.  
  251. /************************************
  252.  ** FUNZIONE PER DEFINIRE UN BOX   **
  253.  ** DI CLIP SULLA FINESTRA         **
  254.  ************************************
  255.  **** INPUT :               **
  256.  ** graf -> valore >0 ritornato    **
  257.  **         dalla funzione d'ini-  **
  258.  **         zializzazione.         **
  259.  ** minx - valore minimo x box.    **
  260.  ** miny - valore minimo y box.    **
  261.  ** dx - larghezza box.           **
  262.  ** dy - altezza box.           **
  263.  **** OUTPUT:               **
  264.  ** > 0 tutto ok, valore effettivo **
  265.  **     larghezza box in pixel.    ** 
  266.  ** = 0 errore.               **
  267.  **** NOTA:               **
  268.  ** elimina eventuali clip region  **
  269.  ** preesistenti.              **
  270.  ** dy max =2999.           **
  271.  ** dx max =2999.           **
  272.  ** Se dx o dy =0 allora ritorna   **
  273.  ** valore effettivo di dx.        **
  274.  ************************************/
  275. long int clipbox(struct grafica *graf,long int minx,
  276.            long int miny,long int dx,long int dy)
  277. {
  278. struct Layer *la;
  279. struct Region *clipr;
  280. struct Rectangle rect;
  281. struct ClipRect *clrt;
  282. long int esi,x,y;
  283. long int i;
  284.  
  285. #ifdef DEBUG
  286. char dbg[80];
  287. #endif
  288.  
  289. if (dx==0 OR dy==0) return(graf->clipdx);
  290.  
  291. x=dx;
  292. y=dy;
  293.  
  294. if (y>MAXDY) y=MAXDY;
  295. if (x>MAXDX) x=MAXDX;
  296.  
  297. i=((x+15)/16)*16;
  298.  
  299. graf->clipx=minx;
  300. graf->clipy=miny;
  301.  
  302. /* se uso libreria ottimizzata */
  303. if (graf->clipdx!=i OR graf->clipdy!=y)
  304.     {
  305.     graf->clipdx=i;
  306.     graf->clipdy=y;
  307. /*
  308.     FreeNBuff(graf);
  309.     InitNBuff(graf);
  310. */
  311.     }
  312.  
  313. return (graf->clipdx);
  314. }
  315.  
  316. /*************************************
  317.  ** FUNZIONE PER CANCELLARE UN BOX  **
  318.  ** NELLA FINESTRA .            **
  319.  *************************************
  320.  **** INPUT :                       **
  321.  ** graf -> valore >0 ritornato da  **
  322.  **         ini_g().                **
  323.  ** x0   -> coord. x punto in alto  **
  324.  **         a sinistra box.         **
  325.  ** y0   -> coord. y punto in alto  **
  326.  **         a sinistra box.         **
  327.  ** x1   -> coord. x punto in basso **
  328.  **         a destra box.        **
  329.  ** y1   -> coord. y punto in basso **
  330.  **        a destra box.        **
  331.  **** NOTA :                **
  332.  ** usa il colore dello sfondo, e   **
  333.  ** non influenza le altre funzioni **
  334.  *************************************/
  335. /*
  336. void cls_b(struct grafica *graf,long int x0,
  337.     long int y0,long int x1,long int y1)
  338. {
  339. long int i;
  340. char c,*db;
  341. if (((long int)graf<=NULL) OR ((long int)(graf->rast)<=NULL)) return(0); 
  342. EraseRect(graf->rast,x0,y0,x1,y1);
  343. }
  344. */
  345.  
  346. /*************************************
  347.  ** FUNZIONE PER CAMBIARE IL MODO   **
  348.  ** VIDEO DI TRACCIAMENTO.          **
  349.  *************************************
  350.  **** INPUT :                       **
  351.  ** graf -> valore >0 ritornato da  **
  352.  **         ini_g().                **
  353.  ** mod  -> nuovo modo video.       **
  354.  **** NOTA :                **
  355.  ** valori per mod :            **
  356.  ** 0 > JAM1 (over 2)            **
  357.  ** 1 > JAM2 (over 0) (def.)        **
  358.  ** 2 > COMPLEMENT (over 1)         **
  359.  ** 4 > INVERSVID  (inverse 1)      **
  360.  *************************************/
  361. void over(struct grafica *graf,long int mod)
  362. {
  363. if (((long int)graf<=NULL) OR ((long int)(graf->rast)<=NULL)) return(0); 
  364.  
  365. SetDrMd(graf->rast,mod);
  366. }
  367.  
  368. /********* ROUTIN INTERNE PER PSEUDO DOUBLE BUFFERING ***************/
  369. /*********************************************
  370.  ** INIZIALIZZO UN DISPLAY BUFFER DI TIPO   **
  371.  ** CHUNKY PER USARE POI WritePixelArray8().** 
  372.  *********************************************
  373.  **** INPUT :                    **
  374.  **** OUTPUT:                    **
  375.  ** se > 0 allora puntatore a nuova rastport**
  376.  *********************************************
  377.  ** nota: la larghezza del box di visualiz. ** 
  378.  **    deve essere un multiplo di 16.       **
  379.  *********************************************/
  380. struct RastPort *InitNBuff(struct grafica *graf)
  381. {
  382. struct RastPort *rport = NULL;  
  383. struct Window *win;
  384. short int err = NULL;
  385. char *c;
  386. long int i;
  387.  
  388. win=graf->wind;
  389.  
  390. graf->tmp_rp.BitMap=NULL;
  391. graf->dbuf=NULL;
  392.  
  393. InitRastPort(&graf->tmp_rp);
  394.  
  395. /** 
  396.    Uso le routin ottimizzate definisco un display buffer tipo chunky e una rastport temp.
  397.    per WritePixelArray8().
  398.    Nota :la larghezza del display buffer deve essere multipla di 16 (una word)).
  399. **/ 
  400. rport=win->RPort;
  401.  
  402. graf->ldbuf=graf->clipdx * graf->clipdy + DIPIU;
  403. graf->dbuf=(char *)AllocMem(graf->ldbuf,NULL);
  404. if (graf->dbuf==NULL) {
  405.     err=1;
  406.     goto NBInit_done ;
  407.     }
  408. graf->tmp_rp.Layer=NULL;
  409. graf->tmp_rp.BitMap=(struct BitMap *)AllocBitMap(graf->clipdx,1,8,                        BMF_CLEAR|BMF_DISPLAYABLE,rport->BitMap);
  410.  
  411. if (graf->tmp_rp.BitMap==NULL) {
  412.     err=2;
  413.     goto NBInit_done ;
  414.     }
  415.  
  416. /* inizializzo il display buffer con tutti 0 */
  417. c=graf->dbuf;
  418. for(i=0 ;i<graf->ldbuf; i++) c[i]=0;
  419.  
  420. NBInit_done:
  421. if (err) FreeNBuff(graf);
  422. return (rport);
  423. }
  424.  
  425. /***************************************************
  426.  ** CHIUDO TUTTE LE AREE APERTE DALLA InitNBuff() **
  427.  ***************************************************/
  428. void FreeNBuff(struct grafica *graf)
  429. {
  430.  
  431. if (graf->dbuf) FreeMem(graf->dbuf,graf->ldbuf);
  432. if (graf->tmp_rp.BitMap) 
  433.     {
  434.     WaitBlit();
  435.     FreeBitMap(graf->tmp_rp.BitMap);  
  436.     }
  437.  
  438. }
  439.  
  440. /********* FUNZIONI GRAFICHE 2D OTTIMIZZATE ********************************/
  441.  
  442. /***********************************
  443.  ** RIEMPIO IL DISPLAY FILE COL   **
  444.  ** COLORE DELLO SFONDO.      **
  445.  ***********************************
  446.  **** INPUT :              **
  447.  ** amb3d -> valore >0 ritornato  **
  448.  **         dalla funzione d'ini- **
  449.  **         zializzazione.        **
  450.  **** OUTPUT:              **
  451.  ** nessuno .              **
  452.  ***********************************/
  453. void cls_f(amb3d)
  454. struct ambient3d *amb3d;
  455. {
  456. char col,*c;
  457. long int i,*z,zz;
  458.  
  459. /* inizializzo il display buffer con gcolor */
  460. c=amb3d->graf->dbuf;
  461. col=amb3d->gcolor;
  462. for(i=0 ;i<amb3d->graf->ldbuf; i++) c[i]=col;
  463.  
  464. /* se definito uno zbuffer lo riempio con z=0x7FFFFFFF */
  465. if (amb3d->graf->zbuf!=NULL)
  466.     {
  467.     z=amb3d->graf->zbuf;
  468.     zz=amb3d->maxx*amb3d->maxy;
  469.     for(i=0 ;i<=zz; i++) z[i]=0x7FFFFFFFL; 
  470.     }
  471.  
  472. }
  473.  
  474. /***********************************
  475.  ** DISEGNO UN PIXEL NEL DISPLAY  **
  476.  ** BUFFER CHUNKY.          **
  477.  ***********************************
  478.  **** INPUT :              **
  479.  ** amb3d -> valore >0 ritornato  **
  480.  **         dalla funzione d'ini- **
  481.  **         zializzazione.        **
  482.  ** buf  -> puntatore ad array di **
  483.  **        short int con coordi- **
  484.  **         nate vertici.      **
  485.  **** OUTPUT:              **
  486.  ** nessuno .              **
  487.  ***********************************/
  488. void pixel(amb3d,buf)
  489. struct ambient3d *amb3d;
  490. struct polytemp *buf;
  491. {
  492. struct grafica *gf;
  493. short int dx;
  494. short int x;
  495. short int y;
  496. long int c,*tcol,ii,*zz;
  497. char *db;
  498.  
  499. gf=amb3d->graf;
  500. db=gf->dbuf;
  501. tcol=gf->t_color;
  502. zz=gf->zbuf;
  503. dx=gf->clipdx;
  504. x=buf->x1;
  505. y=buf->y1;
  506. ii=dx*y+x;
  507. c=tcol[buf->color];
  508. if (c==TRASP) return((void)0);
  509.  
  510. if (amb3d->fzbuf==NULL)
  511.     {
  512.     if (x>=NULL AND x<dx AND y>=NULL AND y<gf->clipdy) db[ii]=c+buf->shade;
  513.     }
  514. else
  515.     {
  516.     if (buf->z1<zz[ii] AND x>=NULL AND x<dx AND y>=NULL AND y<gf->clipdy) 
  517.         {
  518.         db[ii]=c+buf->shade;
  519.         zz[ii]=buf->z1;
  520.         }
  521.     }
  522. }
  523. /***********************************
  524.  ** DISEGNO IL BORDO DI UN POLIGO-**
  525.  ** NO.                  **
  526.  ***********************************
  527.  **** INPUT :              **
  528.  ** amb3d -> valore >0 ritornato  **
  529.  **         dalla funzione d'ini- **
  530.  **         zializzazione.        **
  531.  ** buf  -> puntatore ad array di **
  532.  **        short int con coordi- **
  533.  **         nate vertici.      **
  534.  **** OUTPUT:              **
  535.  ** nessuno .              **
  536.  ***********************************/
  537. void line(amb3d,buf)
  538. struct ambient3d *amb3d;
  539. struct polytemp *buf;
  540. {
  541. long int col,*bcol;
  542.  
  543. bcol=amb3d->graf->t_color;
  544. col=bcol[buf->color]+buf->shade;
  545. if (col==TRASP) return((void)0);
  546.  
  547. switch (buf->numpoints)
  548.     {
  549.     case (2):
  550.         line2(amb3d,buf->x1,buf->y1,buf->z1,buf->x2,buf->y2,buf->z2,col);
  551.         break;
  552.     case (3):
  553.         line2(amb3d,buf->x1,buf->y1,buf->z1,buf->x2,buf->y2,buf->z2,col);
  554.         line2(amb3d,buf->x2,buf->y2,buf->z2,buf->x3,buf->y3,buf->z3,col);
  555.         line2(amb3d,buf->x3,buf->y3,buf->z3,buf->x1,buf->y1,buf->z1,col);
  556.         break;
  557.     case (4):
  558.         line2(amb3d,buf->x1,buf->y1,buf->z1,buf->x2,buf->y2,buf->z2,col);
  559.         line2(amb3d,buf->x2,buf->y2,buf->z2,buf->x3,buf->y3,buf->z3,col);
  560.         line2(amb3d,buf->x3,buf->y3,buf->z3,buf->x4,buf->y4,buf->z4,col);
  561.         line2(amb3d,buf->x4,buf->y4,buf->z4,buf->x1,buf->y1,buf->z1,col);
  562.         break;
  563.     }
  564. }
  565.  
  566. /***********************************
  567.  ** DISEGNO UNA RIGA NEL DISPLAY  **
  568.  ** BUFFER CHUNKY.          **
  569.  ***********************************
  570.  **** INPUT :              **
  571.  ** amb3d -> valore >0 ritornato  **
  572.  **         dalla funzione d'ini- **
  573.  **         zializzazione.        **
  574.  ** x  -> coordinata x partenza.  **
  575.  ** y  -> coordinata y partenza.  **
  576.  ** z  -> valore z iniziale.      **
  577.  ** x1 -> coordinata x arrivo.      **
  578.  ** y1 -> coordinata y arrivo.      **
  579.  ** z1 -> valore z finale.      **
  580.  ** col-> colore riga.          **
  581.  **** OUTPUT:              **
  582.  ** nessuno .              **
  583.  ***********************************/
  584. void line2(amb3d,x,y,z,x1,y1,z1,col)
  585. struct ambient3d *amb3d;
  586. long int x;
  587. long int y;
  588. long int z;
  589. long int x1;
  590. long int y1;
  591. long int z1;
  592. long int col;
  593. {
  594. struct grafica *gf;
  595. char *db;
  596. short int xm,ym,xx;
  597. long int dx,dy,dz;
  598. long int to,from,za,*zz,fz;
  599. long int ii,i,a,b;
  600.  
  601. #ifdef DEBUG
  602. char dbg[100];
  603. #endif
  604.  
  605. gf=amb3d->graf;
  606. db=gf->dbuf;
  607. zz=gf->zbuf;
  608. fz=amb3d->fzbuf;
  609. xm=(short int)gf->clipdx;
  610. ym=(short int)gf->clipdy;
  611. xx=xm;
  612.  
  613. dy=(y1-y)<<PREC;
  614. dx=(x1-x)<<PREC;
  615. dz=z1-z;
  616. if (dy<NULL) dy=-dy;
  617. if (dx<NULL) dx=-dx;
  618. if (dy<dx)
  619.     {
  620.     if (y>y1) dy=-dy;
  621.     dx=dx>>PREC;
  622.     if (dx==NULL) dx=1; 
  623.     dy/=dx;
  624.     if (fz) dz/=dx;
  625.     a=y<<PREC;
  626.     za=z;
  627.     from=x;
  628.     to=x1;
  629.     if (x>x1)
  630.         {
  631.         ii=from;
  632.         from=to;
  633.         to=ii;
  634.         a=y1<<PREC;
  635.         za=z1;
  636.         dy=-dy;
  637.         dz=-dz;
  638.         }
  639.     if (to>=xm) to=xm;
  640.     if (fz==NULL)
  641.         {
  642.         for(b=from ;b<to ;b++) 
  643.             {
  644.             i=a>>PREC;
  645.             if (b>=0 AND i>=0 AND i<ym) db[i*xx+b]=(char)col;
  646.             a+=dy;
  647.             }
  648.         }
  649.     else
  650.         {
  651.         for(b=from ;b<to ;b++) 
  652.             {
  653.             i=a>>PREC;
  654.             ii=i*xx+b;
  655.             if (za<=zz[ii] AND b>=0 AND i>=0 AND i<ym)
  656.                 {
  657.                 db[ii]=(char)col;
  658.                 zz[ii]=za;
  659.                 }
  660.             a+=dy;
  661.             za+=dz;
  662.             }
  663.         }
  664.     }
  665. else
  666.     {
  667.     if (x>x1) dx=-dx;
  668.     dy=dy>>PREC;
  669.     if (dy==NULL) dy=1;
  670.     dx/=dy;
  671.     if (fz) dz/=dy;
  672.     a=x<<PREC;
  673.     za=z;
  674.     from=y;
  675.     to=y1;
  676.     if (y>y1) 
  677.         {
  678.         ii=from;
  679.         from=to;
  680.         to=ii;
  681.         a=x1<<PREC;
  682.         za=z1;
  683.         dx=-dx;
  684.         dz=-dz;
  685.         }
  686.     if (to>=ym) to=ym;
  687.     if (fz==NULL)
  688.         {
  689.         for(b=from ;b<to ;b++) 
  690.             {
  691.             i=a>>PREC;
  692.             if (b>=0 AND i>=0 AND i<xm) db[b*xx+i]=(char)col;
  693.             a+=dx;
  694.             }
  695.         }
  696.     else
  697.         {
  698.         for(b=from ;b<to ;b++) 
  699.             {
  700.             i=a>>PREC;
  701.             ii=b*xx+i;
  702.             if (za<=zz[ii] AND b>=0 AND i>=0 AND i<xm)
  703.                 {
  704.                 db[ii]=(char)col;
  705.                 zz[ii]=za;
  706.                 }
  707.             a+=dx;
  708.             za+=dz;
  709.             }
  710.         }
  711.     }
  712. }
  713.  
  714. /***********************************
  715.  ** DISEGNO UN TRIANGOLO CON LO   **
  716.  ** SHADING RICHIESTO CON O SENZA **
  717.  ** BORDO NEL DISPLAY BUFFER      **
  718.  ** CHUNKY.              **
  719.  ***********************************
  720.  **** INPUT :              **
  721.  ** amb3d -> valore >0 ritornato  **
  722.  **         dalla funzione d'ini- **
  723.  **         zializzazione.        **
  724.  ** buf  -> puntatore a struttura **
  725.  **         polytemp con descri-  **
  726.  **        zione poligono.      ** 
  727.  ** bordo-> =-1 senza bordo       **
  728.  **         >=0 colore bordo.     **
  729.  **** OUTPUT:              **
  730.  ** nessuno .              **
  731.  ***********************************/
  732. void drw_tg(amb3d,buf,bordo)
  733. struct ambient3d *amb3d;
  734. struct polytemp *buf;
  735. long int bordo;
  736. {
  737. struct pixl *vert;
  738. register long int d,i,ii,x1,xs,xe;
  739. long int clb,xm,ym,x,y,c,z,u,v,ys,ye;
  740. long int lmap,*tcol,*pzb,dy,mx,mc,mz,mu,mv,start;
  741. struct grafica *gf;
  742. unsigned char *tmp,*btmap;
  743. struct edge *ledge,*redge;
  744. char zbuf,goraud,texmap;
  745. #ifdef DEBUG 
  746. char dbg[100];
  747. #endif
  748.  
  749. goraud=0;
  750. texmap=0;
  751. zbuf=0;
  752. btmap=0;
  753. lmap=0;
  754. gf=amb3d->graf;
  755. tcol=gf->t_color;
  756. pzb=gf->zbuf;
  757. if (buf->tmap->dtmap!=NULL)
  758.     {
  759.     btmap=buf->tmap->dtmap->chunky;
  760.     lmap=buf->tmap->dtmap->larg;
  761.     }
  762. i=buf->vmode & 0x0F;
  763. if (i==GORAUD) goraud=1;
  764. if (( buf->vmode & TMAP)!=NULL AND btmap!=NULL) texmap=1;
  765. if (pzb!=NULL) zbuf=amb3d->fzbuf;
  766. xm=gf->clipdx-1;
  767. ym=gf->clipdy;
  768. vert=(struct pixl *)amb3d->temp;
  769. ledge=(struct edge *)&vert[5];
  770. redge=(struct edge *)&ledge[MAXDY+2];
  771. tmp=(unsigned char *)gf->dbuf;
  772.  
  773. #ifdef DEBUG
  774. sprintf(dbg,"vert=%ld ledge=%ld redge=%ld tmp=%ld tcol=%ld pzb=%ld \n",vert,ledge,redge,tmp,tcol,pzb,);
  775. write_dbg(dbg);
  776. #endif
  777.  
  778. vert[0].x=buf->x1<<PREC;
  779. vert[0].y=buf->y1;
  780. vert[0].color=buf->clp1<<PREC;
  781. vert[0].z=buf->z1;
  782. vert[0].u=buf->tmap->u1<<PREC;
  783. vert[0].v=buf->tmap->v1<<PREC;
  784. vert[1].x=buf->x2<<PREC;
  785. vert[1].y=buf->y2;
  786. vert[1].color=buf->clp2<<PREC;
  787. vert[1].z=buf->z2;
  788. vert[1].u=buf->tmap->u2<<PREC;
  789. vert[1].v=buf->tmap->v2<<PREC;
  790. vert[2].x=buf->x3<<PREC;
  791. vert[2].y=buf->y3;
  792. vert[2].color=buf->clp3<<PREC;
  793. vert[2].z=buf->z3;
  794. vert[2].u=buf->tmap->u3<<PREC;
  795. vert[2].v=buf->tmap->v3<<PREC;
  796.  
  797. /* riordino i vertici in base alla Y minore con bubble sort */
  798. if (vert[0].y > vert[1].y)
  799.     {
  800.     x=vert[0].x;
  801.     y=vert[0].y;
  802.     z=vert[0].z;
  803.     c=vert[0].color;
  804.     u=vert[0].u;
  805.     v=vert[0].v;
  806.     vert[0].x=vert[1].x;
  807.     vert[0].y=vert[1].y;
  808.     vert[0].z=vert[1].z;
  809.     vert[0].color=vert[1].color;
  810.     vert[0].u=vert[1].u;
  811.     vert[0].v=vert[1].v;
  812.     vert[1].x=x;
  813.     vert[1].y=y;
  814.     vert[1].z=z;
  815.     vert[1].color=c;
  816.     vert[1].u=u;
  817.     vert[1].v=v;
  818.     }    
  819.  
  820. if (vert[1].y > vert[2].y)
  821.     {
  822.     x=vert[1].x;
  823.     y=vert[1].y;
  824.     z=vert[1].z;
  825.     c=vert[1].color;
  826.     u=vert[1].u;
  827.     v=vert[1].v;
  828.     vert[1].x=vert[2].x;
  829.     vert[1].y=vert[2].y;
  830.     vert[1].z=vert[2].z;
  831.     vert[1].color=vert[2].color;
  832.     vert[1].u=vert[2].u;
  833.     vert[1].v=vert[2].v;
  834.     vert[2].x=x;
  835.     vert[2].y=y;
  836.     vert[2].z=z;
  837.     vert[2].color=c;
  838.     vert[2].u=u;
  839.     vert[2].v=v;
  840.     }    
  841.  
  842. if (vert[0].y > vert[1].y)
  843.     {
  844.     x=vert[0].x;
  845.     y=vert[0].y;
  846.     z=vert[0].z;
  847.     c=vert[0].color;
  848.     u=vert[0].u;
  849.     v=vert[0].v;
  850.     vert[0].x=vert[1].x;
  851.     vert[0].y=vert[1].y;
  852.     vert[0].z=vert[1].z;
  853.     vert[0].color=vert[1].color;
  854.     vert[0].u=vert[1].u;
  855.     vert[0].v=vert[1].v;
  856.     vert[1].x=x;
  857.     vert[1].y=y;
  858.     vert[1].z=z;
  859.     vert[1].color=c;
  860.     vert[1].u=u;
  861.     vert[1].v=v;
  862.     }    
  863.  
  864. /* scarto triangoli tutti fuori */
  865. if (vert[0].y<NULL AND vert[2].y<NULL) return(0);
  866. if (vert[0].y>=ym AND vert[2].y>=ym) return(0);
  867.  
  868. /** scan left edges **/
  869. mx=vert[2].x-vert[0].x;
  870. mc=vert[2].color-vert[0].color;
  871. mz=vert[2].z-vert[0].z;
  872. if (texmap)
  873.     {
  874.     mu=vert[2].u-vert[0].u;
  875.     mv=vert[2].v-vert[0].v;
  876.     }
  877. dy=vert[2].y-vert[0].y;
  878. if (dy!=NULL)
  879.     {
  880.     mx/=dy;
  881.     if (texmap)
  882.         {
  883.         mu/=dy;
  884.         mv/=dy;
  885.         }
  886.     if (goraud) mc/=dy;
  887.     if (zbuf) mz/=dy;
  888.     }
  889. x=vert[0].x;
  890. c=vert[0].color;
  891. z=vert[0].z;
  892. u=vert[0].u;
  893. v=vert[0].v;
  894. for (i=vert[0].y ;i<=vert[2].y; i++)
  895.     {
  896.     x1=x>>PREC;
  897.     if (i>=NULL AND i<ym)
  898.         {
  899.         ledge[i].x=x1;
  900.         if (texmap)
  901.             {
  902.             ledge[i].u=u;
  903.             ledge[i].v=v;
  904.             }
  905.         if (goraud) ledge[i].color=c;
  906.         if (zbuf) ledge[i].z=z;    
  907.         }
  908.     c+=mc;
  909.     x+=mx;
  910.     z+=mz;
  911.     if (texmap)
  912.         {
  913.         u+=mu;
  914.         v+=mv;
  915.         }
  916.     }
  917.  
  918. /** scan rigth edges **/
  919. mx=vert[1].x-vert[0].x;
  920. mc=vert[1].color-vert[0].color;
  921. mz=vert[1].z-vert[0].z;
  922. if (texmap)
  923.     {
  924.     mu=vert[1].u-vert[0].u;
  925.     mv=vert[1].v-vert[0].v;
  926.     }
  927. dy=vert[1].y-vert[0].y;
  928. if (dy!=NULL)
  929.     {
  930.     mx/=dy;
  931.     if (texmap)
  932.         {
  933.         mu/=dy;
  934.         mv/=dy;
  935.         }
  936.     if (goraud) mc/=dy;
  937.     if (zbuf) mz/=dy;
  938.     }
  939. x=vert[0].x;
  940. c=vert[0].color;
  941. z=vert[0].z;
  942. u=vert[0].u;
  943. v=vert[0].v;
  944. for (i=vert[0].y ;i<=vert[1].y; i++)
  945.     {
  946.     x1=x>>PREC;
  947.     if (i>=NULL AND i<ym)
  948.         {
  949.         redge[i].x=x1;
  950.         if (texmap)
  951.             {
  952.             redge[i].u=u;
  953.             redge[i].v=v;
  954.             }
  955.         if (goraud) redge[i].color=c;
  956.         if (zbuf) redge[i].z=z;
  957.         }
  958.     c+=mc;
  959.     x+=mx;
  960.     z+=mz;
  961.     if (texmap)
  962.         {
  963.         u+=mu;
  964.         v+=mv;
  965.         }
  966.     }
  967.  
  968. mx=vert[2].x-vert[1].x;
  969. mc=vert[2].color-vert[1].color;
  970. mz=vert[2].z-vert[1].z;
  971. if (texmap)
  972.     {
  973.     mu=vert[2].u-vert[1].u;
  974.     mv=vert[2].v-vert[1].v;
  975.     }
  976. dy=vert[2].y-vert[1].y;
  977. if (dy!=NULL)
  978.     {
  979.     mx/=dy;
  980.     if (texmap)
  981.         {
  982.         mu/=dy;
  983.         mv/=dy;
  984.         }
  985.     if (goraud) mc/=dy;
  986.     if (zbuf) mz/=dy;
  987.     }
  988. x=vert[1].x;
  989. c=vert[1].color;
  990. z=vert[1].z;
  991. u=vert[1].u;
  992. v=vert[1].v;
  993. for (i=vert[1].y ;i<=vert[2].y; i++)
  994.     {
  995.     x1=x>>PREC;
  996.     if (i>=NULL AND i<ym)
  997.         {
  998.         redge[i].x=x1;
  999.         if (texmap)
  1000.             {
  1001.             redge[i].u=u;
  1002.             redge[i].v=v;
  1003.             }
  1004.         if (goraud) redge[i].color=c;
  1005.         if (zbuf) redge[i].z=z;
  1006.         }
  1007.     c+=mc;
  1008.     x+=mx;
  1009.     z+=mz;
  1010.     if (texmap)
  1011.         {
  1012.         u+=mu;
  1013.         v+=mv;
  1014.         }
  1015.     }
  1016.  
  1017. /** draw scan lines **/
  1018. ys=vert[0].y;
  1019. if (ys<NULL) ys=0;
  1020. if (ys>ym-1) ys=ym-1;
  1021. ye=vert[2].y;
  1022. if (ye<NULL) ye=0;
  1023. if (ye>ym-1) ye=ym-1;
  1024.  
  1025. start=(ys-1)*(xm+1);
  1026.  
  1027. for (i=ys ;i<=ye ;i++)
  1028.     {
  1029.     start+=xm+1;
  1030.     xs=ledge[i].x;
  1031.     xe=redge[i].x;
  1032.     if (xe>xm AND xs>xm) continue;
  1033.     if (xe<NULL AND xs<NULL) continue;
  1034.     clb=tcol[buf->color];
  1035.     c=buf->shade;
  1036.     if (xs<xe)
  1037.         {
  1038.         mx=(xe-xs);
  1039.         if (mx!=NULL)
  1040.             {
  1041.             if (texmap) 
  1042.                 {
  1043.                 mu=(redge[i].u-ledge[i].u)/mx;
  1044.                 mv=(redge[i].v-ledge[i].v)/mx;
  1045.                 }
  1046.             if (goraud) mc=(redge[i].color-ledge[i].color)/mx;
  1047.             if (zbuf) mz=(redge[i].z-ledge[i].z)/mx;
  1048.             }
  1049.         if (zbuf) z=ledge[i].z+FIXVM;
  1050.         if (goraud) c=ledge[i].color+FIXVM;
  1051.         if (texmap)
  1052.             {
  1053.             u=ledge[i].u+FIXVM;
  1054.             v=ledge[i].v+FIXVM;
  1055.             }
  1056.         }
  1057.     else 
  1058.         {
  1059.         mx=(xs-xe);
  1060.         if (mx!=NULL)
  1061.             {
  1062.             if (texmap)
  1063.                 {
  1064.                 mu=(ledge[i].u-redge[i].u)/mx;
  1065.                 mv=(ledge[i].v-redge[i].v)/mx;
  1066.                 }
  1067.             if (goraud) mc=(ledge[i].color-redge[i].color)/mx;
  1068.             if (zbuf) mz=(ledge[i].z-redge[i].z)/mx;
  1069.             }
  1070.         if (zbuf) z=redge[i].z+FIXVM;
  1071.         if (goraud) c=redge[i].color+FIXVM;
  1072.         if (texmap)
  1073.             {
  1074.             u=redge[i].u+FIXVM;
  1075.             v=redge[i].v+FIXVM;
  1076.             }
  1077.         x=xs;
  1078.         xs=xe;
  1079.         xe=x;
  1080.         }
  1081.     if (xe>xm) xe=xm;
  1082.     if (goraud)
  1083.         {
  1084.         if (zbuf)
  1085.             {
  1086.             for (ii=xs ;ii<=xe ;ii++)
  1087.                 {
  1088.                 d=start+ii;
  1089.                 if (z<pzb[d] AND ii>=NULL )
  1090.                     {
  1091.                     if (texmap) clb=tcol[btmap[(v>>PREC)*lmap +                                           (u>>PREC)]];
  1092.                     if (clb!=TRASP)
  1093.                         {
  1094.                         pzb[d]=z; 
  1095.                         tmp[d]=clb+(c>>PREC);
  1096.                         }
  1097.                     }
  1098.                 c+=mc;
  1099.                 z+=mz;
  1100.                 if (texmap)
  1101.                     {
  1102.                     u+=mu;
  1103.                     v+=mv;
  1104.                     }
  1105.                 }
  1106.             }
  1107.         else
  1108.             {    
  1109.             for (ii=xs ;ii<=xe ;ii++)
  1110.                 {
  1111.                 if (ii>=NULL)
  1112.                     {
  1113.                     if (texmap) clb=tcol[btmap[(v>>PREC)*lmap + 
  1114.                                    (u>>PREC)]];
  1115.                     if (clb!=TRASP) tmp[start+ii]=clb+(c>>PREC);
  1116.                     }
  1117.                 c+=mc;
  1118.                 if (texmap)
  1119.                     {
  1120.                     u+=mu;
  1121.                     v+=mv;
  1122.                     }
  1123.                 }
  1124.             }
  1125.         }
  1126.     else    
  1127.         {
  1128.         if (zbuf)
  1129.             {
  1130.             for (ii=xs ;ii<=xe ;ii++)
  1131.                 {
  1132.                 d=start+ii;
  1133.                 if (z<pzb[d] AND ii>=NULL)
  1134.                     {
  1135.                     if (texmap) clb=tcol[btmap[(v>>PREC)*lmap + 
  1136.                                    (u>>PREC)]];
  1137.                     if (clb!=TRASP)
  1138.                         {
  1139.                         pzb[d]=z; 
  1140.                         tmp[d]=clb+c;
  1141.                         }
  1142.                     }
  1143.                 z+=mz;
  1144.                 if (texmap)
  1145.                     {
  1146.                     u+=mu;
  1147.                     v+=mv;
  1148.                     }
  1149.                 }
  1150.             }        
  1151.         else
  1152.             {
  1153.             for (ii=xs ;ii<=xe ;ii++) 
  1154.                 {
  1155.                 if (ii>=NULL)
  1156.                     {
  1157.                     if (texmap) clb=tcol[btmap[(v>>PREC)*lmap + 
  1158.                                    (u>>PREC)]];
  1159.                     if (clb!=TRASP) tmp[start+ii]=clb+c;
  1160.                     }
  1161.                 if (texmap)
  1162.                     {
  1163.                     u+=mu;
  1164.                     v+=mv;
  1165.                     }
  1166.                 }
  1167.             }        
  1168.         }
  1169.     }
  1170. /* traccio eventuale bordo */
  1171.  
  1172. if (bordo>=NULL)
  1173.     {
  1174.     line2(amb3d,buf->x1,buf->y1,buf->z1-DISP,buf->x2,buf->y2,buf->z2-DISP,bordo);
  1175.     line2(amb3d,buf->x2,buf->y2,buf->z2-DISP,buf->x3,buf->y3,buf->z3-DISP,bordo);
  1176.     line2(amb3d,buf->x3,buf->y3,buf->z3-DISP,buf->x1,buf->y1,buf->z1-DISP,bordo);
  1177.     }
  1178.  
  1179. }
  1180.  
  1181. /***********************************
  1182.  ** DISEGNO UN QUADRILATERO CON O **
  1183.  ** SENZA BORDO NEL CHUNKY BUFFER **
  1184.  ** CON LO SHADING RICHIESTO      **
  1185.  ***********************************
  1186.  **** INPUT :              **
  1187.  ** amb3d-> valore >0 ritornato   **
  1188.  **         dalla funzione d'ini- **
  1189.  **         zializzazione.        **
  1190.  ** buf  -> puntatore a struttura **
  1191.  **         polytemp con descri-  **
  1192.  **        zione poligono.      ** 
  1193.  ** bordo-> =-1 senza bordo       **
  1194.  **         >=0 colore bordo.     **
  1195.  **** OUTPUT:              **
  1196.  ** nessuno .              **
  1197.  ***********************************/
  1198. void drw_qg(amb3d,buf,bordo)
  1199. struct ambient3d *amb3d;
  1200. struct polytemp *buf;
  1201. long int bordo;
  1202. {
  1203. struct grafica *gf;
  1204. struct polytemp pt;
  1205. struct poltmap ptm,*ptmo; 
  1206. short int buf1[6];
  1207.  
  1208. gf=amb3d->graf;
  1209. ptmo=buf->tmap;
  1210. pt.x1=buf->x3;
  1211. pt.y1=buf->y3;
  1212. pt.x2=buf->x4;
  1213. pt.y2=buf->y4;
  1214. pt.x3=buf->x1;
  1215. pt.y3=buf->y1;
  1216. pt.numpoints=buf->numpoints;
  1217. pt.obj=buf->obj;
  1218. pt.npol=buf->npol;
  1219. pt.color=buf->color;
  1220. pt.shade=buf->shade;
  1221. pt.vmode=buf->vmode;
  1222. pt.clp1=buf->clp3;
  1223. pt.clp2=buf->clp4;
  1224. pt.clp3=buf->clp1;
  1225. pt.z1=buf->z3;
  1226. pt.z2=buf->z4;
  1227. pt.z3=buf->z1;
  1228. pt.tmap=&ptm;
  1229.  
  1230. ptm.dtmap=ptmo->dtmap;
  1231. ptm.u1=ptmo->u3;
  1232. ptm.v1=ptmo->v3;
  1233. ptm.u2=ptmo->u4;
  1234. ptm.v2=ptmo->v4;
  1235. ptm.u3=ptmo->u1;
  1236. ptm.v3=ptmo->v1;
  1237.  
  1238. drw_tg(amb3d,buf,-1);
  1239. drw_tg(amb3d,&pt,-1);
  1240. /* traccio eventuale bordo */
  1241.  
  1242. if (bordo>=NULL)
  1243.     {
  1244.     line2(amb3d,buf->x1,buf->y1,buf->z1-DISP,buf->x2,buf->y2,buf->z2-DISP,bordo);
  1245.     line2(amb3d,buf->x2,buf->y2,buf->z2-DISP,buf->x3,buf->y3,buf->z3-DISP,bordo);
  1246.     line2(amb3d,buf->x3,buf->y3,buf->z3-DISP,buf->x4,buf->y4,buf->z4-DISP,bordo);
  1247.     line2(amb3d,buf->x4,buf->y4,buf->z4-DISP,buf->x1,buf->y1,buf->z1-DISP,bordo);
  1248.     }
  1249.  
  1250. }
  1251.  
  1252.